home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <math.h>
- #include <stdlib.h>
-
- #include "DeskLib:ColourTran.h"
- #include "DeskLib:Sprite.h"
- #include "DeskLib:Screen.h"
- #include "DeskLib:SWI.h"
-
- #include "Shell.Redraw2.h"
- #include "Shell.RedrawToSp.h"
- #include "Shell.Printf.h"
- #include "Shell.FindWind.h"
- #include "Shell.Extra.h"
-
-
-
-
-
-
- /*#define SWI_OS_SpriteOP 0x62*/
-
-
-
-
- BOOL Shell_SaveRectAsSprite( char *filename, Shell_rectblock *r, BOOL greyscale)
- /* Most of this fn is taken up by finding the space for a sprite and */
- /* initialising it. The actual redrirect + redraw is fairly simple. */
- {
- int areasize, savesize, dummy;
- wimp_point size;
- sprite_areainfo *areainfo;
- sprite_outputstate oldstate;
- void *savebuffer;
- int spritemode;
- FILE *f;
-
- f = fopen( filename, "w");
- if (!f) return FALSE;
-
- Screen_CacheModeInfo();
- spritemode = (greyscale) ? 21 : screen_mode;
-
- size.x = r->rect.max.x - r->rect.min.x;
- size.y = r->rect.max.y - r->rect.min.y;
-
- areasize = sizeof( sprite_areainfo) +
- Sprite_MemorySize(
- size.x >> screen_eig.x, /* X-size of sprite in pixels. */
- size.y >> screen_eig.y, /* Y-size of sprite in pixels. */
- spritemode,
- sprite_HASNOMASKPAL
- );
-
- if ( greyscale) areasize += 2048; /* extra space for the 256-entry palette. */
-
- areainfo = (sprite_areainfo *) malloc( areasize);
- if ( !areainfo) {
- Error_Report( 0, Error_PLACE "Shell can't malloc %i bytes for spritearea.", areasize);
- return TRUE;
- }
-
- areainfo->areasize = areasize;
- areainfo->numsprites = 0;
- areainfo->firstoffset = 16;
- areainfo->freeoffset = 16;
- Sprite_InitArea( (sprite_area) areainfo);
-
- if ( Sprite_Create(
- (sprite_area) areainfo,
- "Output",
- 0, /* no palette */
- size.x >> screen_eig.x , /* x size of sprite in pixels. */
- size.y >> screen_eig.y, /* y size of sprite in pixels. */
- spritemode
- )
- )
- {
- Error_Report( 0, Error_PLACE "Shell can't create sprite for saving");
- free( areainfo);
- return TRUE;
- }
-
- if (greyscale) {
- /* Add a 256-entry grey-scale palette to the created sprite, as per PRMs 1-832. */
- sprite_header *spriteheader = (sprite_header *) &areainfo[1];
- int *palette = (int *) &spriteheader[1];
- int i;
-
- areainfo->freeoffset += 2048;
- spriteheader->offset_next += 2048;
- spriteheader->imageoffset += 2048;
- spriteheader->maskoffset += 2048;
-
- for ( i=0; i<256; i++) { palette_entry p;
- p.value = 0;
- p.data.red = p.data.green = p.data.blue = i;
- palette[2*i] = palette[2*i+1] = p.value; /* Why do we need 2 of each */
- } /* palette entry ??? */
- }
-
-
- /* Find size of savebuffer. */
- SWI( 3, 3, SWI_OS_SpriteOp, 256+62, areainfo, "Output", &dummy, &dummy, &savesize);
- savebuffer = calloc( 1, savesize);
-
- if ( !savebuffer) {
- Error_Report(
- 0, Error_PLACE "Shell can't calloc %i bytes for savebuffer for sprite-redirection", savesize
- );
- free( areainfo);
- return TRUE;
- }
-
- Sprite_Redirect( (sprite_area) areainfo, "Output", savebuffer, &oldstate);
-
- /*
- {
- int in[8] = { 162, 163, -1};
- int out[8];
- SWI( 2, 0, 0x31, in, out);
- Shell_WaitPrintf( "Text chr size inside sprite-redirection is (x,y) = (%i, %i)\n",
- out[0], out[1]
- );
- }
- */
-
- /* Now redraw the area */
- {
- Shell_windblock *wind = Shell_FindWindBlock( r->window);
- Shell_convertpoint convert;
-
- /* Make all plotting (to sprite) be relative to r->rect by */
- /* giving the Shell redraw functions a doctored */
- /* Shell_convertpoint. */
-
- /* All Shell functions use 'convert' to plot to the screen, and */
- /* convert.x/y can be looked on as the screen coors of (0,0) */
- /* workarea coors. Hence if we pretend that (0,0) workarea is */
- /* at (-rect.min.x/y), rect.min.x/y will get mapped to 0,0 */
- /* which will make all redrawing of rect fit the sprite */
- /* perfectly! */
- convert.x = -r->rect.min.x;
- convert.y = -r->rect.min.y;
-
-
- if (greyscale) {
- /* Clear the sprite to white. This isn't necesary when */
- /* the sprite has no mask because colour 0 (which is */
- /* all pixels are because sprite is calloc-ed rather */
- /* than malloc-ed) is white when there is no mask. */
- /* With our grey-scale mask, colour 0 is in fact black. */
- /* Could possibly fill the palette in in reverse to */
- /* make colour 0 white, but that would be a bit of a */
- /* hack... */
- palette_entry p;
- p.value = 0;
- p.data.red = 255;
- p.data.green = 255;
- p.data.blue = 255;
- ColourTrans_SetGCOL( p.value, 0 /* No ECFs */, 0 /* gcol action */);
- Shell_RectangleFill( &r->rect, convert);
- }
-
- Shell_WindRedraw2( &r->rect, convert, wind);
- }
-
-
-
- Sprite_UnRedirect( &oldstate);
-
- /* Save the created sprite to whatever file handle we were given <Wimp$Scrap> for */
- /* data transfers, and a normal filename if save was to the filer. */
- fwrite( &areainfo->numsprites, sizeof( char), areasize, f);
-
- free( areainfo);
- /* I'm not sure whether one should tell the OS that this area */
- /* has been removed... */
-
- free( savebuffer);
- fclose(f);
-
- return TRUE;
- }
-
-
-